<?php

/*后台控制器*/

class adminController extends Ue
{

    public $errorInfo = ['code' => 404, 'msg' => '访问页面不存在'];
    public $pageName = ['index' => '首页', 'home' => '总览', 'kami_list' => '卡密管理', 'kami_group' => '卡密分组', 'logs' => '运行日志', 'app' => '应用设置', 'set' => '系统设置'];//页面名称
    public $pageEnums = 10;

    public $app, $appid, $admConf, $appConf;

    //__init 函数会在控制器被创建时自动运行用于初始化工作，如果您要使用它，请按照以下格式编写代码即可：

    public function __init()
    {
        $this->ip = t('ip')->getIp();//获取客户端IP
        if (!defined('U_ADMIN')) {
            if (md5($this->ip) != getCookies('admatt')) {
                $this->errorInfo = ['code' => 500, 'msg' => '管理后台已关闭，请使用后台入口访问进入'];
                $this->display('404.php');
                die();
            }
            define('U_ADMIN', TRUE);
        } else {
            setCookies('admatt', md5($this->ip));
            header('location:/admin');
        }
        $this->times = time();
        $this->admConf = c('admin');
        $this->appConf = c('app');
        $this->Jwt = t('Jwt', $this->admConf['SYS_SAFEKEY'])->setIss($this->admConf['ADM_USER']);

        if (!in_array(U_M, ['login'])) {//登录检测
            $this->__checkLogin();//检查登录
        }

        if (!in_array(U_M, ['login', 'index', 'logout'])) {//应用检测
            $this->appid = getCookies('appid');
            if (intval($this->appid) < 0) {
                $this->display(U_C . '/null.php');
                die();
            }
            $this->app = db('app')->where('id = ?', [$this->appid])->fetch();
            if (!$this->app) {
                $this->display(U_C . '/null.php');
                die();
            }
        }
        $this->pageEnums = $this->appConf['APP_PAGE_ENUMS'];//每一页显示数据的条数
    }

    protected function __checkLogin()
    {//检查登录
        $this->admcookies = getCookies('admcookies');
        if (!$this->admcookies) {
            if (U_POST) {
                $this->json('登录后操作', 201);
            }
            header('location:/admin/login');
        } else {
            if (!$this->__checkCookies()) {
                header('location:/admin/login');
            }
        }
    }

    public function __checkCookies()
    {//检查cookies
        $verifyResult = $this->Jwt->verifyToken($this->admcookies);
        if (!$verifyResult) return false;
        $this->pName = isset($this->pageName[U_M]) ? $this->pageName[U_M] : $this->pageName['index'];
        $app_name = isset($this->app) ? $this->app['app_name'] : "";
        $this->title = $this->pName . ' - 管理中心 - ' . $app_name;
        return true;
    }

    protected function __log($type, $code = 200)
    {//记录日志
        if ($this->appConf['APP_ADM_LOG'] == 'on') {
            db('logs')->add(['type' => $type, 'time' => $this->times, 'ip' => $this->ip, 'code' => $code]);
        }//记录日志
    }

    public function login()
    {//登录
        $this->admcookies = getCookies('admcookies');
        if ($this->admcookies) {
            if ($this->__checkCookies()) {
                header('location:/admin');
            }
        }
        if (U_POST) {
            $checkRules = [
                'user' => ['wordnum', '5,18', '账号不规范'],
                'password' => ['Password', '6,18', '密码不规范']
            ];
            $dataChecker = t('dataChecker', $_POST, $checkRules);
            $res = $dataChecker->check();
            if (!$res) $this->json($dataChecker->error, 201);

            if ($this->admConf['ADM_USER'] == $_POST['user'] && $this->admConf['ADM_PASSWORD'] == md5($_POST['password'] . $this->admConf['SYS_SAFEKEY'])) {
                $token = $this->Jwt->getToken();
                setCookies('admcookies', $token, 24 * 60 * 60);
                $this->__log(U_M);//记录日志
                $this->json('登录成功');
            } else {
                $this->__log(U_M, 201);//记录日志
                $this->json('账号密码不正确', 201);
            }
        }
    }

    public function logout()
    {//退出登录
        delCookies("admcookies");
        header('location:/admin/login');
    }

    public function index()
    {
        if (U_POST) {
            $checkRules = [
                'act' => ['sameone', 'get,add,del', '操作类型有误'],
                'pg' => ['int', '1,11', '页面有误', 1, 'get'],
                'name' => ['string', '2,64', '应用名称不规范', ['add' => false]],
                'bb' => ['between', '1,999', '应用版本号应在1~999区间', ['add' => '1.0']],
                'appid' => ['int', '1,11', '应用配置继承ID有误', ['add' => 0]],
                'del_id' => ['int', '1,11', '删除应用ID有误', ['del' => false]],
            ];
            $dataChecker = t('dataChecker', $_POST, $checkRules);
            $res = $dataChecker->check();
            if (!$res) $this->json($dataChecker->error, 201);

            $db = db('app');
            if ($_POST['act'] == 'get') {//获取APP列表
                $this->pageEnums = 12;
                $page = isset($_POST['pg']) ? (intval($_POST['pg']) >= 1 ? intval($_POST['pg']) : 1) : 1;

//                $list = $db->join("as A LEFT JOIN (SELECT appid,COUNT(*) AS us FROM {$db->pre}user GROUP BY appid) AS U ON (A.id=U.appid) LEFT JOIN (SELECT appid,COUNT(*) AS ks FROM {$db->pre}kami GROUP BY appid) AS K ON (A.id=K.appid)")->order('id desc')->page($page,$this->pageEnums)->fetchAll('A.*,IFNULL(U.us,0) as u_total,IFNULL(K.ks,0) as k_total');
                $list = $db->order('id desc')->page($page, $this->pageEnums)->fetchAll();
                $this->json('获取成功', 200, $list);
            } elseif ($_POST['act'] == 'add') {//添加APP
                $res = $db->where('app_name = ?', [$_POST['name']])->fetch();
                if ($res) $this->json("应用名称重复", 201);

                $add_data = ['app_name' => $_POST['name'], 'app_key' => md5(getcode(10) . uniqid())];

                if (count($_FILES) > 0 && isset($_FILES['file_applogo'])) {
                    $uper = t('uper', 'file_applogo', 'assets/logo');
                    $uploadedFile = $uper->upload();
                    if (!$uploadedFile) {
                        $this->json('LOGO上传错误 : ' . $uper->error, 201);
                    }
                    $add_data['app_logo'] = $uploadedFile;
                }

                if ($_POST['appid'] > 0) {
                    $app_res = $this->db->where('id = ?', [$_POST['appid']])->fetch();
                    if (!$app_res) $this->json('继承应用不存在', 201);
                    unset($app_res['id']);
                    unset($app_res['app_name']);
                    unset($app_res['app_key']);
                    unset($app_res['app_logo']);
                    $add_data = array_merge($add_data, $app_res);
                }

                $app_ver_db = db('app_ver');
                $kami_group_db = db('kami_group');
                $db->beginTransaction();
                $add_id = $db->add($add_data);
                if ($add_id) {
                    // 添加默认版本
                    $app_ver_res = $app_ver_db->add(['appid' => $add_id, 'ver_val' => $_POST['bb'] ? : '1.0']);
                    // 添加默认分组
                    $default_kami_group = array(
                        array('name' => '小时卡', 'val' => 3600, 'clientmax' => 1),
                        array('name' => '天卡', 'val' => 86400, 'clientmax' => 1),
                        array('name' => '周卡', 'val' => 604800, 'clientmax' => 1),
                        array('name' => '月卡', 'val' => 2592000, 'clientmax' => 1),
                        array('name' => '季卡', 'val' => 7776000, 'clientmax' => 1),
                        array('name' => '半年卡', 'val' => 15552000, 'clientmax' => 1),
                        array('name' => '年卡', 'val' => 31536000, 'clientmax' => 2),
                        array('name' => '永久卡', 'val' => 9999999999, 'clientmax' => 3)
                    );
                    foreach ($default_kami_group as $item) {
                        $kami_group_data = ['app_id' => $add_id, 'name' => $item['name'], 'val' => $item['val'], 'clientMax' => $item['clientmax']];
                        $kami_group_res = $kami_group_db->add($kami_group_data);
                    }
                    if ($app_ver_res && $kami_group_res) {
                        $db->commit();
                    } else {
                        $db->rollback();
                        $this->json('版本创建失败，请重试', 201);
                    }
                    $list = $db->where('id = ?', [$add_id])->fetch();
                    $this->app['id'] = $add_id;
                    $this->__log('app_add');//记录日志

                    $this->json('创建成功', 200, ['list' => [$list]]);
                }
                $this->json('应用创建失败，请重试', 201, $this->db->error());
            } elseif ($_POST['act'] == 'del') {//删除APP
                $db = $db->where('id = ?', [$_POST['del_id']]);
                $this->app['id'] = $_POST['del_id'];
                if ($db) {
                    db('kami_list')->where('app_id = ?', [$_POST['del_id']])->delete();//清空卡密
                    db('kami_group')->where('app_id = ?', [$_POST['del_id']])->delete();//清空卡密组
                    db('app_ver')->where('appid = ?', [$_POST['del_id']])->delete();//清除版本
                    $res = $db->delete();
                    $this->__log('app_del');//记录日志
                    $this->json('删除成功');
                } else {
                    $this->__log('app_del', 201);//记录日志
                    $this->json('删除失败', 201);
                }
            } else {
                $this->json('操作有误', 201);
            }
        }
    }

    public function home()
    {
        if (U_POST) {
            $checkRules = ['act' => ['sameone', 'get', '操作类型有误']];
            $dataChecker = t('dataChecker', $_POST, $checkRules);
            $res = $dataChecker->check();
            if (!$res) $this->json($dataChecker->error, 201);

            if ($_POST['act'] == 'get') {
                if (!isset($this->app) || !$this->app) $this->json('应用访问失败：该应用不存在', 201);
                $data_res = m('admin')->getHome($this->appid);
                $this->json('成功', 200, array_merge($this->app, ['census' => $data_res]));
            }
        }
    }

    public function kami_list()
    {//卡密管理
        if (U_POST) {
            $checkRules = [
                'act' => ['sameone', 'get,add,edit,del,reward,get_kmg,logs,del_client', '操作类型有误'],
                'pg' => ['int', '1,11', '页面有误', true, 1],
                'so' => ['string', '1,64', '搜索内容不规范', true],
                'id' => ['int', '1,11', '操作ID有误', ['act', 'edit,del,logs,del_client']],
                'gid' => ['int', '1,11', '卡密分组有误', ['act', 'add']],
                'length' => ['betweend', '16,32', '卡密长度有误', ['act', 'add']],
                'pre' => ['Kami', '1,10', '卡密前缀不规范：1~10位字符', ['act', 'add', true]],
                'num' => ['betweend', '1,10000', '卡密生成数量有误，一次最多生成1W张', ['act', 'add']],
                'out' => ['sameone', 'y,n', '导出状态有误', ['act', 'add']],
                'note' => ['String', '1,64', '卡密备注不规范', ['act', 'edit,add', true]],
                'vipExp' => ['int', '1,11', '会员到期不规范', ['act', 'edit', true]],
                'banExp' => ['int', '1,11', '禁用卡密期限不规范', ['act', 'edit', true]],
                'banMsg' => ['String', '1,128', '禁用通知不规范', ['act', 'edit', true]],
                'password' => ['Password', '6,18', '密码不规范', ['act', 'edit', true]],
                'clientmax' => ['int', '1,2', '客户端最大值有误', ['act', 'edit']],
                'cid' => ['string', '5,32', '解绑设备ID有误', ['act', 'del_client']],
                'reward_kmg' => ['int', '1,11', '奖励分组有误', ['act', 'reward']],
                'reward_val' => ['int', '1,10', '奖励值有误', ['act', 'reward']],
            ];
            $dataChecker = t('dataChecker', $_POST, $checkRules);
            $res = $dataChecker->check();
            if (!$res) $this->json($dataChecker->error, 201);

            $this->db = db(U_M);
            if ($_POST['act'] == 'get') {
                $page = isset($_POST['pg']) ? (intval($_POST['pg']) >= 1 ? intval($_POST['pg']) : 1) : 1;

                $this->db = $this->db->join("as K LEFT JOIN {$this->db->pre}kami_group as KG on (K.gid = KG.id)");
                $this->db = $this->db->where('K.app_id = ?', [$this->appid]);
                if (isset($_POST['so']) && !empty($_POST['so'])) {
                    $this->db = $this->db->where('K.cardNo LIKE ? or K.cardEmail LIKE ? or K.cardNote LIKE ? or KG.name LIKE ?', ['%' . $_POST['so'] . '%', '%' . $_POST['so'] . '%', '%' . $_POST['so'] . '%', '%' . $_POST['so'] . '%']);
                }
                $res_all = $this->db->order('K.id desc')->page($page, $this->pageEnums)->fetchAll('K.*,KG.name as Gname');
                if (!$res_all) $this->json('数据获取失败', 201);
                $this->json('成功', 200, $res_all);
            }

            if ($_POST['act'] == 'add') {//添加
                $kg_res = db('kami_group')->where('id = ?', [$_POST['gid']])->fetch();
                if (!$kg_res) $this->json("卡密组不存在", 201);

                if ($_POST['out'] == 'y') {
                    $excel = tool('PHPExcel');//基础信息
                    $excel->getActiveSheet(0)->setTitle($kg_res['name'] . '卡密表');//设置 sheet 名称
                    $excel->setActiveSheetIndex(0)->setCellValue('A1', '序号')->setCellValue('B1', '卡号')->setCellValue('C1', '备注')->setCellValue('D1', '卡密组')->setCellValue('E1', '应用');//表头
                }
//                $this->json($_POST, 200);
                for ($i = 1; $i <= $_POST['num']; $i++) {
                    $pre = $_POST['pre'] != "" ? $_POST['pre'] : "";
                    $key = $pre . strtoupper(str_shuffle(uniqid()) . getcode($_POST['length'] - 13));
                    $add = [
                        'gid' => $_POST['gid'],
                        'app_id' => $this->appid,
                        'cardNote' => $_POST['note'],
                        'cardNo' => $key,
                        'cardVal' => $kg_res['val'],
                        'setTime' => $this->times,
                        'setIP' => $this->ip,
                        'clientMax' => $kg_res['clientMax'],
                        'outTime' => $_POST['out'] == 'y' ? time() : NULL,
                    ];

                    $add_id = $this->db->add($add);//添加卡密
                    if ($add_id) {
                        if ($_POST['out'] == 'y') {
                            $excel->setActiveSheetIndex(0)->setCellValue('A' . ($i + 1), $i)->setCellValue('B' . ($i + 1), $key)->setCellValue('C' . ($i + 1), $_POST['note'])->setCellValue('D' . ($i + 1), $kg_res['name'])->setCellValue('E' . ($i + 1), $this->app['app_name']);
                        }
                    } else {
                        $i--;
                    }
                }
                if ($_POST['out'] == 'y') {
                    $objWriter = PHPExcel_IOFactory::createWriter($excel, 'Excel5');
                    $xlsname = (!empty($_POST['pre']) ? ($_POST['pre'] . '_') : '') . $_POST['num'] . '_' . date('YmdHis', $this->times) . '.xls';
                    $objWriter->save('data/kami/' . $xlsname);//保存为 xls
                    $this->json('生成成功', 200, ['downUrl' => '/admin/down/' . $xlsname]);
                } else {
                    $this->json('生成成功', 200);
                }

            }

            if ($_POST['act'] == 'edit') {//编辑
                $query_res = $this->db->where('id = ?', [$_POST['id']])->fetch();
                if (!$query_res) $this->json('编辑卡密ID不存在', 201);

                $data = ['cardNote' => $_POST['note'], 'vipExp' => $_POST['vipExp'], 'clientMax' => $_POST['clientmax'], 'banExp' => $_POST['banExp'], 'banMsg' => $_POST['banMsg']];
                if (empty($query_res['useTime']) && $_POST['vipExp'] > 0) $this->json('当前卡密未使用，不可编辑VIP到期时间', 201);
                if (!empty($query_res['useID'])) $this->json('当前卡密已被充值使用，不可编辑', 201);

                if (isset($_POST['password']) && !empty($_POST['password'])) {
                    $data['cardPwd'] = md5($_POST['password']);
                }
                $up_res = $this->db->where('id = ?', [$_POST['id']])->update($data);
                if ($up_res) {
                    if ($this->db->rowCount() < 1) $this->json('编辑失败：未修改任何数据', 201);
                    $res = $this->db->join("as K LEFT JOIN {$this->db->pre}kami_group as KG on (K.gid = KG.id)")->where('K.id = ?', [$_POST['id']])->fetch('K.*,KG.name as Gname');
                    if (!$res) $this->json('编辑成功，数据返回失败：' . $this->db->error(), 201);
                    $this->__log(U_M . '_edit');//记录日志
                    $this->json('编辑成功', 200, ['list' => [$res]]);
                } else {
                    $this->__log(U_M . '_edit', 201);//记录日志
                    $this->json('编辑失败', 201);
                }
            }

            if ($_POST['act'] == 'del') {//删除
                $res = $this->db->where('id = ?', [$_POST['id']])->delete();
                if ($res) {
                    $this->__log(U_M . '_del');//记录日志
                    $this->json('删除成功');
                } else {
                    $this->__log(U_M . '_del', 201);//记录日志
                    $this->json('删除失败', 201);
                }
            }

            if ($_POST['act'] == 'get_kmg') {//获取卡密组
                $res_all = db('kami_group')->where('app_id = ?', [$this->appid])->fetchAll("id,name");
                if (!$res_all) $this->json('数据获取失败', 201);
                $this->json('成功', 200, ['list' => $res_all]);
            }

            if ($_POST['act'] == 'logs') {//获取日志
                $this->logType = c('logType');
                $logs_all = db('logs')->where('uid = ?', [$_POST['id']])->limit(0, 5)->fetchAll("type,time,ip,code");
                $logs_list = [];
                foreach ($logs_all as $rows) {
                    $logs_list[] = [
                        'actType' => !empty($this->logType[$rows['type']]) ? $this->logType[$rows['type']] : $rows['type'],
                        'time' => date("Y-m-d H:i", $rows['time']),
                        'ip' => $rows['ip'],
                        'state' => $rows['code'] == 200 ? 'y' : 'n'
                    ];
                }
                $this->json('成功', 200, ['logs' => $logs_list]);
            }

            if ($_POST['act'] == 'del_client') {//删除已登录设备
                $client_res = $this->db->where('id = ?', [$_POST['id']])->fetch('clientID');
                if (!$client_res) $this->json('编辑卡密ID不存在', 201);
                $client_arr = json_decode($client_res['clientID'], true);

                $client = [];
                foreach ($client_arr as $rows) {
                    if ($rows['udid'] != $_POST['cid']) {
                        $client[] = ['udid' => $rows['udid'], 'time' => $rows['time']];
                    }
                }

                $data = ['clientID' => json_encode($client)];
                $res = $this->db->where('id = ?', [$_POST['id']])->update($data);
                if ($res) {
                    $this->__log('client_del');//记录日志
                    $this->json('解绑成功');
                } else {
                    $this->__log('client_del', 201);//记录日志
                    $this->json('解绑失败', 201);
                }
            }

            if ($_POST['act'] == 'reward') {//奖励
                if ($_POST['reward_kmg'] == 0) {//奖励全部组
                    $res = $this->db->where('vipExp < ? and vipExp > ?', [9999999999, time()])->field('vipExp', $_POST['reward_val']);
                } else {
                    $res = $this->db->where('gid = ? and vipExp < ? and vipExp > ?', [$_POST['reward_kmg'], 9999999999, time()])->field('vipExp', $_POST['reward_val']);
                }
                if ($res) {
                    $this->__log(U_M . '_reward');//记录日志
                    $this->json('奖励已发放完成,共计奖励数：' . $this->db->rowCount());
                } else {
                    $this->__log(U_M . '_reward', 201);//记录日志
                    $this->json('奖励发布失败', 201);
                }
            }
        }
    }

    public function kami_group()
    {//卡密分组
        if (U_POST) {
            $checkRules = [
                'act' => ['sameone', 'get,add,edit,del', '操作类型有误'],
                'pg' => ['int', '1,11', '页面有误', true],
                'so' => ['string', '1,64', '搜索内容不规范', true],
                'id' => ['int', '1,11', '操作ID有误', ['act', 'edit,del']],
                'name' => ['String', '2,64', '卡密组名称不规范', ['act', 'edit,add']],
                'val' => ['int', '1,10', '卡密面值有误', ['act', 'edit,add']],
                'clientmax' => ['int', '1,2', '客户端最大值有误', ['act', 'edit,add']],
            ];
            $dataChecker = t('dataChecker', $_POST, $checkRules);
            $res = $dataChecker->check();
            if (!$res) $this->json($dataChecker->error, 201);

            $this->db = db(U_M);
            if ($_POST['act'] == 'get') {
                $page = isset($_POST['pg']) ? (intval($_POST['pg']) >= 1 ? intval($_POST['pg']) : 1) : 1;

                $this->db = $this->db->join("as KG LEFT JOIN (SELECT gid,COUNT(*) AS kms,count(case when useTime>0  then 1 end) as kmuses FROM {$this->db->pre}kami_list GROUP BY gid) AS K ON (KG.id=K.gid)");
                $this->db = $this->db->where('KG.app_id = ?', [$this->appid]);
                if (isset($_POST['so']) && !empty($_POST['so'])) {
                    $this->db = $this->db->where('KG.name LIKE ?', ['%' . $_POST['so'] . '%']);
                }

                $res_all = $this->db->order('KG.id desc')->page($page, $this->pageEnums)->fetchAll('KG.*,IFNULL(K.kms,0) as km_num,IFNULL(K.kmuses,0) as km_uses');
                if (!$res_all) $this->json('数据获取失败', 201);
                $this->json('成功', 200, $res_all);
            }

            if ($_POST['act'] == 'add') {
                $res = $this->db->where('name = ?', [$_POST['name']])->fetch();
                if ($res) $this->json("卡密组已存在", 201);
                $data = ['app_id' => $this->appid, 'name' => $_POST['name'], 'val' => $_POST['val'], 'clientMax' => $_POST['clientmax']];
                $add_id = $this->db->add($data);
                if ($add_id) {
                    $res = $this->db->join("as KG LEFT JOIN (SELECT gid,COUNT(*) AS kms,count(case when useTime>0  then 1 end) as kmuses FROM {$this->db->pre}kami_list GROUP BY gid) AS K ON (KG.id=K.gid)")->where('KG.id = ?', [$add_id])->fetch('KG.*,IFNULL(K.kms,0) as km_num,IFNULL(K.kmuses,0) as km_uses');
                    $this->__log(U_M . '_add');//记录日志
                    $this->json('添加成功', 200, ['list' => [$res]]);
                } else {
                    $this->__log(U_M . '_add', 201);//记录日志
                    $this->json('添加失败', 201);
                }
            }

            if ($_POST['act'] == 'edit') {
                $query_res = $this->db->where('name = ?', [$_POST['name']])->fetch();
                if ($query_res && $query_res['id'] != $_POST['id']) $this->json('编辑失败，重复卡密组名称', 201);

                $data = ['name' => $_POST['name'], 'val' => $_POST['val'], 'clientMax' => $_POST['clientmax']];
                $up_res = $this->db->where('id = ?', [$_POST['id']])->update($data);
                if ($up_res) {
                    $res = $this->db->join("as KG LEFT JOIN (SELECT gid,COUNT(*) AS kms,count(case when useTime>0  then 1 end) as kmuses FROM {$this->db->pre}kami_list GROUP BY gid) AS K ON (KG.id=K.gid)")->where('KG.id = ?', [$_POST['id']])->fetch('KG.*,IFNULL(K.kms,0) as km_num,IFNULL(K.kmuses,0) as km_uses');
                    $this->__log(U_M . '_edit');//记录日志
                    $this->json('编辑成功', 200, ['list' => [$res]]);
                } else {
                    $this->__log(U_M . '_edit', 201);//记录日志
                    $this->json('编辑失败', 201);
                }
            }

            if ($_POST['act'] == 'del') {//删除
                $res = $this->db->where('id = ?', [$_POST['id']])->delete();
                if ($res) {
                    $this->__log(U_M . '_del');//记录日志
                    $this->json('删除成功');
                } else {
                    $this->__log(U_M . '_del', 201);//记录日志
                    $this->json('删除失败', 201);
                }
            }
        }
    }


    public function logs()
    {//日志
        $this->logType = c('logType');
        if (U_POST) {
            $checkRules = [
                'act' => ['sameone', 'get', '操作类型有误'],
                'pg' => ['int', '1,11', '页面有误', true],
                'so' => ['string', '1,64', '搜索内容不规范', true],
                'type' => ['string', '1,64', '搜索类型不规范', true, 'all'],
            ];
            $dataChecker = t('dataChecker', $_POST, $checkRules);
            $res = $dataChecker->check();
            if (!$res) $this->json($dataChecker->error, 201);

            $this->db = db(U_M);
            if ($_POST['act'] == 'get') {
                $page = isset($_POST['pg']) ? (intval($_POST['pg']) >= 1 ? intval($_POST['pg']) : 1) : 1;
                $this->db = $this->db->join("as LOG left join {$this->db->pre}kami_list as K on (LOG.uid = K.id)");
                if ($_POST['type'] != 'all') {
                    if (isset($_POST['so']) && !empty($_POST['so'])) {
                        $this->db = $this->db->where('LOG.type LIKE ? and (K.cardNo LIKE ? or K.cardEmail LIKE ?)', ['%' . $_POST['type'] . '%', '%' . $_POST['so'] . '%', '%' . $_POST['so'] . '%']);
                    } else {
                        $this->db = $this->db->where('LOG.type LIKE ?', ['%' . $_POST['type'] . '%']);
                    }
                } else {
                    if (isset($_POST['so']) && !empty($_POST['so'])) {
                        $this->db = $this->db->where('K.cardNo LIKE ? or K.cardEmail LIKE ?', ['%' . $_POST['so'] . '%', '%' . $_POST['so'] . '%']);
                    }
                }
                $res_all = $this->db->order('LOG.id desc')->page($page, $this->pageEnums)->fetchAll('LOG.*,K.cardNo,K.cardEmail');
                if (!$res_all) $this->json('数据获取失败', 201);
                $list = [];
                foreach ($res_all['list'] as $rows) {
                    $actUser = empty($rows['uid']) ? 'admin' : (!empty($rows['cardEmail']) ? $rows['cardEmail'] : $rows['cardNo']);
                    $list[] = [
                        'id' => $rows['id'],
                        'actType' => !empty($this->logType[$rows['type']]) ? $this->logType[$rows['type']] : $rows['type'],
                        'actPerson' => empty($rows['uid']) ? '管理员' : '用户',
                        'actUser' => $actUser,
                        'time' => date("Y-m-d H:i", $rows['time']),
                        'ip' => $rows['ip'],
                        'state' => $rows['code'] == 200 ? 'y' : 'n'
                    ];
                }
                $res_all['list'] = $list;
                $this->json('成功', 200, $res_all);
            }
        }
    }

    public function app()
    {//应用设置
        if (U_POST) {
            $checkRules = [
                'app_name' => ['String', '2,64', '应用名称不规范'],
                'app_key' => ['wordnum', '16,32', '应用KEY必须是字母+数字16~32位', true],
                'app_mode' => ['sameone', 'y,n', '应用模式有误'],
                'app_state' => ['sameone', 'on,off', '应用状态有误'],
                'app_off_msg' => ['string', '2,255', '应用关闭通知内容不规范', true],
                'api_encrypt' => ['sameone', 'on,off', '数据加密状态有误'],
                'api_sign' => ['sameone', 'on,off', '数据签名状态有误'],
                'api_data_exp' => ['Int', '1,5', '数据有效期设置有误，建议范围：0-99999'],
                'api_heartbeat' => ['Int', '1,5', '心跳有效期设置有误，建议范围：0-99999'],
                'user_client_untie' => ['sameone', 'y,n', '允许自解绑设备状态有误'],
                'user_client_untie_cycle' => ['between', '0,31536000', '解绑周期设置有误，建议范围：0~31536000', true, 0],
                'user_client_untie_punish' => ['between', '-86400,0', '解绑惩罚设置有误，建议范围：-86400~0', true, 0],
            ];

            $dataChecker = t('dataChecker', $_POST, $checkRules);
            $res = $dataChecker->check();
            if (!$res) $this->json($dataChecker->error, 201);
            $db = db('app');
            $update = [ // 其实这里可以直接使用$_POST，但是我都写了，就不删了
                'app_name' => $_POST['app_name'],
                'app_key' => $_POST['app_key'],
                'app_mode' => $_POST['app_mode'],
                'app_state' => $_POST['app_state'],
                'app_off_msg' => $_POST['app_off_msg'],
                'api_sign' => $_POST['api_sign'],
                'api_encrypt' => $_POST['api_encrypt'],
                'api_data_exp' => $_POST['api_data_exp'],
                'api_heartbeat' => $_POST['api_heartbeat'],
                'user_client_untie' => $_POST['user_client_untie'],
                'user_client_untie_punish' => $_POST['user_client_untie_punish'],
                'user_client_untie_cycle' => $_POST['user_client_untie_cycle'],
            ];
            $update_res = $db->where('id = ?', [$this->appid])->update($update);
            if ($update_res) {
                $this->__log(U_M);//记录日志
                $this->json('编辑成功');
            } else {
                $this->__log(U_M, 201);//记录日志
                $this->json('编辑失败', 201);
            }
        }
    }

    public function rsa_key()
    {// 生成RSA密钥
        if (U_POST) {
            $config = [
                'private_key_bits' => 1024,
                'private_key_type' => OPENSSL_KEYTYPE_RSA,
            ];
            $res = openssl_pkey_new($config);
            if ($res === false) { // 为了兼容Windows，实际windows使用的很少
                $opensslConfigPath = str_replace('php-cgi.exe', 'extras\\ssl\\openssl.cnf', PHP_BINARY);
                $config['config'] = $opensslConfigPath;
                $res = openssl_pkey_new($config);
            }
            if ($res === false) { // 如果还是失败，那就无法了
                $this->json('生成密钥对失败', 201);
            }
            // 获取私钥
            $privkey = '';
            if (!openssl_pkey_export($res, $privkey, NULL, $config)) {
                $this->json('导出私钥失败: ' . openssl_error_string(), 201);
            }
            // 获取公钥
            $pubKey = openssl_pkey_get_details($res);
            $pubKey = $pubKey['key'];
            $db = db('app');
            $update = ['api_key' => json_encode(['public' => $pubKey, 'private' => $privkey])];
            $update_res = $db->where('id = ?', [$this->appid])->update($update);
            if ($update_res) {
                $this->json('成功', 200, array('public' => $pubKey, 'app_id' => $this->appid));
            } else {
                $this->json('生成密钥对失败', 201);
            }

        }
    }

    public function smtp()
    {//邮箱设置
        if (U_POST) {
            $checkRules = [
                'crc_length' => ['between', '4,6', '验证码长度有误，建议范围：4~6位数'],
                'crc_exp' => ['between', '1,30', '验证码有效期有误，建议范围：30分钟内'],
                'smtp_host' => ['string', '8,64', '邮箱发信服务器设置有误', true],
                'smtp_port' => ['Int', '2,4', '邮箱端口设置有误', true],
                'smtp_user' => ['string', '4,64', '邮箱发信账号设置有误', true],
                'smtp_pass' => ['string', '4,64', '邮箱发信密码设置有误', true],
            ];

            $dataChecker = t('dataChecker', $_POST, $checkRules);
            $res = $dataChecker->check();
            if (!$res) $this->json($dataChecker->error, 201);
            $data = [
                'CRC_LENGTH' => $_POST['crc_length'],
                'CRC_EXP' => $_POST['crc_exp'],
                'SMTP_HOST' => $_POST['smtp_host'],
                'SMTP_PORT' => $_POST['smtp_port'],
                'SMTP_USER' => $_POST['smtp_user'],
                'SMTP_PASS' => $_POST['smtp_pass']
            ];
            $res = cAlter('admin', $data);
            if ($res) {
                $this->__log(U_M);//记录日志
                $this->json('编辑成功');
            } else {
                $this->__log(U_M, 201);//记录日志
                $this->json('编辑失败', 201);
            }
        }
    }

    public function ver()
    {//版本设置
        if (U_POST) {
            $checkRules = [
                'act' => ['sameone', 'get,add,edit,edit_state,del', '操作类型有误'],
                'pg' => ['int', '1,11', '页面有误', ['get' => 1]],
                'id' => ['int', '1,11', '操作版本ID有误', ['edit,del' => false]],
                'ver_val' => ['between', '1,999', '应用版本号应在1~999区间', ['add' => '1.0', 'edit' => false]],
                'ver_name' => ['string', '2,64', '版本名称不规范', ['add,edit' => false]],
                'ver_key' => ['wordnum', '2,16', '版本索引不规范', ['add,edit' => false]],
                'ver_new_url' => ['Url', '2,128', '更新地址不规范', ['add,edit' => true]],
                'ver_new_content' => ['string', '2,255', '更新内容不规范', ['add,edit' => true]],
                'mi_time' => ['int', '1,11', '时差校验值不规范', ['add,edit' => 0]],
                'mi_rc4_key' => ['Password', '10,32', 'RC4加密密钥长度应该>=10~32', ['add,edit' => true]],
                'mi_aes_key' => ['string', '32,32', 'AES加密密钥长度必须为32', ['add,edit' => true]],
                'mi_aes_iv' => ['string', '16,16', 'AES加密IV长度必须为16', ['add,edit' => true]],
                'mi_public_key' => ['string', '200,300', 'RSA公钥内容不规范', ['add,edit' => true]],
                'mi_private_key' => ['string', '800,900', 'RSA私钥内容不规范', ['add,edit' => true]],
                'ver_off_msg' => ['string', '2,255', '版本关闭通知内容不规范', ['add,edit' => '当前版本维护中']],
                'mi_type' => ['sameone', 'rsa,rc4,ase', '加密类型有误', ['add' => 'rc4', 'edit' => true]],
                'mi_sign' => ['sameone', 'off,on', '数据签名状态操作有误', ['add' => 'off', 'edit' => false, 'edit_state' => true]],
                'mi_state' => ['sameone', 'off,on', '数据加密状态操作有误', ['add' => 'off', 'edit' => false, 'edit_state' => true]],
                'ver_state' => ['sameone', 'off,on', '版本开关状态操作有误', ['add' => 'on', 'edit' => false, 'edit_state' => true]],
            ];

            $dataChecker = t('dataChecker', $_POST, $checkRules);
            $res = $dataChecker->check();
            if (!$res) $this->json($dataChecker->error, 201);
            $db = db('app_ver');
            if ($_POST['act'] == 'get') {//获取
                $this->pageEnums = 12;
                $page = isset($_POST['pg']) ? (intval($_POST['pg']) >= 1 ? intval($_POST['pg']):1) : 1;
                $ver_list = $db->where('appid = ?',[$this->app['id']])->order('id desc')->page($page,$this->pageEnums)->fetchAll();
                if(!$ver_list)$this->json('版本列表获取失败',201);

                $this->json('版本列表获取成功',200,$ver_list);
            }
        }
    }

    public function set()
    {//系统设置
        if (U_POST) {
            $checkRules = [
                'app_page_enums' => ['Int', '1,4', '页面数据条数有误', true, 10],
                'app_adm_log' => ['sameone', 'on,off', '管理员日志设置有误', true, 'on'],
                'app_user_log' => ['sameone', 'on,off', '用户日志设置有误', true, 'on'],
                'api_run_cost' => ['sameone', 'on,off', 'API运算成本设置有误', true, 'on'],
                'api_out_type' => ['sameone', 'json,xml', '系统输出格式设置有误', true, 'json'],
                'sys_debug' => ['sameone', 'y,n', '系统输出格式设置有误', true, 'json'],
            ];
            $dataChecker = t('dataChecker', $_POST, $checkRules);
            $res = $dataChecker->check();
            if (!$res) $this->json($dataChecker->error, 201);

            $indexdata = file_get_contents('index.php');
            if ($_POST['sys_debug'] == 'y') {
                if (!U_DEBUG) {
                    $indexdata = str_replace("'U_DEBUG',FALSE", "'U_DEBUG',TRUE", $indexdata);
                }
            } else {
                if (U_DEBUG) {
                    $indexdata = str_replace("'U_DEBUG',TRUE", "'U_DEBUG',FALSE", $indexdata);
                }
            }
            file_put_contents('index.php', $indexdata);
            $data = [
                'APP_PAGE_ENUMS' => (int)$_POST['app_page_enums'],
                'APP_ADM_LOG' => $_POST['app_adm_log'],
                'APP_USER_LOG' => $_POST['app_user_log'],
                'API_RUN_COST' => $_POST['api_run_cost'],
                'API_OUT_TYPE' => $_POST['api_out_type'],
            ];

            $res = cAlter('admin', $data);
            if ($res) {
                $this->__log(U_M);//记录日志
                $this->json('编辑成功');
            } else {
                $this->__log(U_M, 201);//记录日志
                $this->json('编辑失败', 201);
            }
        }
    }

    public function down()
    {//下载
        if (empty($this->gets) || empty($this->gets[0])) {
            $this->display('404.php');
            die();
        }
        if (file_exists('data/kami/' . $this->gets[0])) {
            t('download')->download('data/kami/' . $this->gets[0], $this->gets[0], true);
        } else {
            $this->errorInfo = ['code' => 500, 'msg' => '文件不存在'];
            $this->display('404.php');
            die();
        }
    }

    public function cap()
    {//修改账号密码
        if (U_POST) {
            $checkRules = [
                'user' => ['wordnum', '5,18', '账号不规范'],
                'pwd' => ['Password', '6,18', '密码不规范'],
                'newpwd' => ['Password', '6,18', '新密码不规范', true]
            ];
            $dataChecker = t('dataChecker', $_POST, $checkRules);
            $res = $dataChecker->check();
            if (!$res) $this->json($dataChecker->error, 201);

            if ($this->admConf['ADM_PASSWORD'] == md5($_POST['pwd'] . $this->admConf['SYS_SAFEKEY'])) {
                $user = $_POST['user'];
                $newpwd = $_POST['newpwd'];
                if (empty($newpwd) && $user == $this->admConf['ADM_USER']) $this->json('未修改任何参数', 201);

                $userdata = file_get_contents(U_CONF . U_D . 'admin.php');
                $userdata = preg_replace("/'ADM_USER'=>'.*?'/", "'ADM_USER'=>'{$user}'", $userdata);
                if (!empty($newpwd)) {
                    $newpwd = md5($newpwd . $this->admConf['SYS_SAFEKEY']);
                    $userdata = preg_replace("/'ADM_PASSWORD'=>'.*?'/", "'ADM_PASSWORD'=>'{$newpwd}'", $userdata);
                }
                $res = file_put_contents(U_CONF . U_D . 'admin.php', $userdata);
                if ($res) {
                    $this->__log(U_M);//记录日志
                    delCookies("admcookies");
                    $this->json('修改成功');
                } else {
                    $this->__log(U_M, 201);//记录日志
                    $this->json('密码错误', 201);
                }
            }
            $this->json('当前密码错误', 201);
        }
    }

}
